#ifndef LINE_H
#define LINE_H

#include <cmath>
#include "vector2d.hpp"

class Line
{
	public:

	Line(Number _a,Number _b,Number _c):a(_a),b(_b),c(_c)
	{}

	Line(Vector2d B,Number _c = 0):
		c(_c)
	{
		Number l = B.length();
		a=(-B.y)/l;
		b=(B.x)/l;
	}

	Line(Vector2d A,Vector2d B):
		 a(A.y-B.y)
		,b(B.x-A.x)
		,c(A.x*B.y - A.y*B.x)
	{}

	Number gety(float x) const
	{
		return -(a*x + c)/b;
	}

	Number getx(float y) const
	{
		return -(b*y + c)/a;
	}

	Number normalize()
	{
		Number l = hypot(a,b);  // dlugosc wektora ab
		if(l==1) return l; // jezeli juz znormalizowany szkoda czasu
		a/=l;
		b/=l;
		c/=l;
		return l;
	}

	Number distance(Vector2d v) const
	{
		return (a*v.x + b*v.y + c) / hypot(a,b); // odleglosc>0 po prawej stronie, po lewej <0, 0 na srodku
	}

	Vector2d projection(Vector2d v) //rzutowanie na prosta
	{
		normalize();
		Number o = a*v.x + b*v.y + c;
		return v + Vector2d(a,b)*o;
	}

	// true jeżeli punkt p leży po lewej stronie (po tej przeciwnej stronie wskazywanej przez wektor normalny)
	bool operator< (Vector2d v) const
	{
		return a*v.x + b*v.y + c < 0;
	}

	// true jeżeli punkt v leży po prawej stronie (po tej stronie wskazywanej przez wektor normalny)
	bool operator> (Vector2d v) const
	{
		return a*v.x + b*v.y + c > 0;
	}

	// true jeżeli punkt v leży po lewej stronie lub na prostej (po tej przeciwnej stronie wskazywanej przez wektor normalny)
	bool operator<= (Vector2d v) const
	{
		return a*v.x + b*v.y + c < EPSILON;
	}

	// true jeżeli punkt v leży po prawej stronie lub na prostej (po tej stronie wskazywanej przez wektor normalny)
	bool operator>= (Vector2d v) const
	{
		return a*v.x + b*v.y + c > -EPSILON;
	}

	// true jeżeli punkt p leży na prostej
	bool operator== (Vector2d v) const
	{
		return std::abs(a*v.x + b*v.y + c) < EPSILON;
	}

	// true jeżeli punkt p nie leży na prostej
	bool operator!= (Vector2d v) const
	{
		return std::abs(a*v.x + b*v.y + c) > EPSILON;
	}

	Number a; // [a,b] to wektor normalny prostej (tylko gdy znormalizowany)
	Number b;
	Number c; // odleglosc prostej od punktu 0,0 (tylko gdy znormalizowany)

};



#endif // LINE_H
